<?
// <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

function show_msg($msg, $url = "")
{
	if ( $url ) {
		?>
		<script language=javascript>
		<!--
		alert("<?=$msg?>");
		location.replace("<?=$url?>");
		//-->
		</script>
		<?
	} else {
		?>
		<script language=javascript>
		<!--
		alert("<?=$msg?>");
		//-->
		</script>
		<?
	}
}

function close_window()
{
	?>
	<script language=javascript>
	<!--
	self.opener=self;
	self.close();
	//-->
	</script>
	<?
}

function close_window_msg($msg = "")
{
	?>
	<script language=javascript>
	<!--
	alert("<?=$msg?>");
	window.close();
	//-->
	</script>
	<?
}

function reload_opener()
{
	?>
	<script language=javascript>
	<!--
	opener.location.reload();
	//-->
	</script>
	<?
}


function change_location($url)
{
	?>
	<script language=javascript>
	<!--
	location.replace("<?=$url?>");
	//-->
	</script>
	<?
}

function open_window($url,$target, $width, $height)
{
	if ( !$width ) $width = 640;
	if ( !$height ) $height = 480;
	?>
	<script language=javascript>
	<!--
	window.open('<?=$url?>', "<?=$target?>", "status=no,toolbar=no,scrollbars=no,width=<?=$width?>,height=<?=$height?>");		
	//-->
	</script>
	<?
}


function print_confim_process($msg, $suffix="")
{
	if ( $suffix ) $name = "process_{$suffix}";
	else $name = "process";
	?>
	<script language="javascript">
	function <?=$name?>(url) {
		if(confirm('<?=$msg?>')) {
			window.open(url, "_blank", "status=no,toolbar=no,scrollbars=no,width=640,height=480");		
		} 
	}
	</script>
	<?
}



function print_option($value, $text, $svalue)
{
	if ($value == $svalue) {
		echo "<option value='$value' selected>$text</option>";
	} else {
		echo "<option value='$value'>$text</option>";
	}
}


function add_to_query($str)
{
	$str = str_replace("'", "''", $str);		// 
	$str = str_replace("\\", "\\\\" , $str);	// 실제로는 \ 를 \\로 변환
	return $str;
}


function is_upper($str)
{
	return ('A' <= $str && $str <= 'Z' );
}


function del_string($str, $len)
{
	if ( strlen($str) > $len ) {
		$newstr = substr($str, 0, $len-3);
		$str = sprintf("%s ...", $newstr);
	}
	return $str;
}

function print_list_from_table_name($table_name, $option=array())
{
	$max_input_size = 12;
	$max_line_size = 50;

	$query = "select * from $table_name where 1 limit 1";
	$result = mysql_query($query) or die("\n<br>Query:$query\n<br>Error:".mysql_error());
	
	$field_object_array = array();
	for ( $i = 0 ; $i < mysql_num_fields($result) ; $i++ ) {
		$field_object = mysql_fetch_field($result, $i);
		$field_object_array[] = $field_object;
	}
	
	echo "\n<p><form name='form1' method='post' action=''>";
	foreach ( $field_object_array as $field_object ) {
		$name  = $field_object->name; 
		$numeric = $field_object->numeric;
		
		if ( $numeric ) {
			$size = 8;
			$max_length = 8;
		} else {
			$size = $max_input_size;
			$max_length = 255;
		}

		if ( $sum_size > $max_line_size ) {
			echo "\n<br>";
			$sum_size = 0;
		}
		$sum_size += $size;
		$value = $_REQUEST["query_{$name}"];

		echo "\n  $name <input type='text' name='query_{$name}' size='$size' maxlength='$max_length' value='$value'>";
	}
	echo "\n<select name='show'>";
	if (isset($_REQUEST['show'])) $show = $_REQUEST['show'];
	else $show = "200";
	print_option("200","200",$show);
	print_option("1000","1000",$show);
	print_option("","ALL",$show);
	echo "\n</select>";
	echo "\n<input type='submit' name='Submit' value='Submit'>";
	echo "\n</form></p>";

	// select
	if ( $option['print_field'] ) $print_field = $option['print_field'];
	else $print_field = "*";

	// where	
	foreach ( $field_object_array as $field_object ) {
		$name  = $field_object->name;
		$value = $_REQUEST["query_{$name}"];
		if ( !$value ) continue;
		if ( strpos($value, "%") === false ) $where .= " and $name = '$value'";
		else $where .= " and $name like '$value'";
	}
	if ( $option['print_where'] ) $where .= " ".$option['print_where'];

	// order_by
	if ( $option['print_order_by'] ) $order_by = "order by {$option['print_order_by']}";
	else $order_by = "";

	// limit
	if ( $show ) $limit = " limit $show";
	
	if ( $where || $limit) {
		$query = "select $print_field from $table_name where 1 $where $order_by $limit";
		$option['table_name'] = $table_name;
		print_list_from_query($query, $option);	
	}
}


function print_list_from_query($query, $option=array())
{
	if ( $option['allow_delete'] ) {
		print_confim_process("정말로 삭제하시겠습니까?", "delete");
	}

	echo "\n<p>".htmlentities($query)."</p>";
	$result = mysql_query($query) or die("\n<br>Query:$query\n<br>Error:".mysql_error());
	
	echo "\n<table cellspacing='1' cellpadding='3' class='simple_table'>";
	$field_array = array();
	$primary_array = array();
	$field_obj_array = array();
	for ( $i = 0 ; $i < mysql_num_fields($result) ; $i++ ) {
		$field_obj = mysql_fetch_field($result, $i);
		$f = $field_obj->name;
		$t = $field_obj->table;
		if ( $option['hide'][$t][$f] ) continue;

		$field_array[] = $f;
		if ( $field_obj->primary_key ) $primary_array[] = $f;
		$field_obj_array[] = $field_obj;
	}
	if ( count($primary_array) == 0 ) $primary_array = $field_array;

	$allow_function = false;
	if ( $option['allow_update'] || $option['allow_delete'] ) $allow_function = true;
	

	echo "\n<tr>";
	foreach ( $field_array as $f ) echo "\n<td valign='top'><strong>$f</strong></td>";
	if ( $allow_function ) echo "\n<td valign='top'><strong>[function]</strong></td>";
	echo "\n</tr>";
	
	while( $row = mysql_fetch_array($result) ) {
		echo "\n<tr>";
		foreach ( $field_obj_array as $obj ) {
			$f = $obj->name;
			$t = $obj->table;
			
			$f_idx = "";
			if ( isset($option['print_data_set_a']["{$t}.{$f}"]) ) $f_idx = "{$t}.{$f}";
			else if ( isset($option['print_data_set_a'][$f]) ) $f_idx = $f;
			if ( $f_idx ) {
				$a_tag = $option['print_data_set_a'][$f_idx];

				if ( $a_tag['href'] ) eval("\$href = \"{$a_tag['href']}\";");
				else $href = "";
				if ( $a_tag['target'] ) eval("\$target = \"{$a_tag['target']}\";");
				else $target = "";
				if ( $a_tag['label'] ) eval("\$label = \"{$a_tag['label']}\";");
				else $label = "";
				if ( $a_tag['title'] ) eval("\$title = \"{$a_tag['title']}\";");
				else $title = "";
				
				if ( $href ) $print_href = " href='$href'";
				else $print_href = "";
				if ( $target ) $print_target = " target='$target'";
				else $print_target = "";
				if ( $title ) $print_title = " title='$title'";
				else $print_title = "";
				
				$left = $a_tag['left'];
				$right = $a_tag['right'];
				
				$print_data = "{$left}<a{$print_href}{$print_target}{$print_title}>{$label}</a>{$right}";

			} else {

				$print_data = $row[$f];
			}
			
			$f_idx = "";
			if ( isset($option['print_data_add_a']["{$t}.{$f}"]) ) $f_idx = "{$t}.{$f}";
			else if ( isset($option['print_data_add_a'][$f]) ) $f_idx = $f;
			if ( $f_idx ) {
				$print_add = "";
				foreach ( $option['print_data_add_a'][$f_idx] as $a_tag ) {

					if ( $a_tag['href'] ) eval("\$href = \"{$a_tag['href']}\";");
					else $href = "";
					if ( $a_tag['target'] ) eval("\$target = \"{$a_tag['target']}\";");
					else $target = "";
					if ( $a_tag['label'] ) eval("\$label = \"{$a_tag['label']}\";");
					else $label = "";
					if ( $a_tag['title'] ) eval("\$title = \"{$a_tag['title']}\";");
					else $title = "";
					
					if ( $href ) $print_href = " href='$href'";
					else $print_href = "";
					if ( $target ) $print_target = " target='$target'";
					else $print_target = "";
					if ( $title ) $print_title = " title='$title'";
					else $print_title = "";
					
					$left = $a_tag['left'];
					$right = $a_tag['right'];
					
					$print_add .= "{$left}<a{$print_href}{$print_target}{$print_title}>{$label}</a>{$right}";
				}
			} else {
				$print_add = "";
			}
			echo "\n<td valign='top'>{$print_data}{$print_add}</td>";
		}

		if ( $allow_function ) {

			$update_id_set = "";
			$delete_id_set = "";
			foreach ( $primary_array as $field ) {
				$update_id_set .= "&".sprintf("%s=%s", urlencode($field), urlencode($row[$field]));

				$delete_id_set .= "&condition_key_".sprintf("%s=%s", urlencode($field), urlencode($row[$field]));
			}
			
			if ( $option['editor_update'] ) eval("\$editor_update = \"{$option['editor_update']}\";");
			else $editor_update = "../lib_common/editor_1d.php?cmd=update&table={$option['table_name']}{$update_id_set}&reload_opener={$option['reload_opener']}&close_window_msg={$option['close_window_msg']}";

			if ( $option['editor_delete'] ) eval("\$editor_delete = \"{$option['editor_delete']}\";");
			else $editor_delete = "../lib_common/editor_1d_process.php?cmd=delete&table={$option['table_name']}{$delete_id_set}&reload_opener={$option['reload_opener']}&close_window_msg={$option['close_window_msg']}";
			
			$print_data = "";
			if ( $option['allow_update'] ) $print_data .= "\n<a target='_blank' href='{$editor_update}'>edit</a>";
			if ( $option['allow_delete'] ) $print_data .= "\n<a target='_blank' href='{$editor_delete}'>del</a>";
			echo "\n<td valign='top'>{$print_data}</td>";
		}
		echo "\n</tr>";
	}
	echo "\n</table>";
	if ( $option['allow_insert'] ) {
		if ( $option['editor_insert'] ) eval("\$editor_insert = \"{$option['editor_insert']}\";");
		else $editor_insert = "../lib_common/editor_1d.php?cmd=insert&table={$option['table_name']}&reload_opener={$option['reload_opener']}&close_window_msg={$option['close_window_msg']}";
		echo "\n<p><a target='_blank' href='{$editor_insert}'>new</a></p>";
	}
}


function make_tree_parse_list($str_val_list, $delimiter=".")
{
	$rtn = array();
	foreach ($str_val_list as $str => $val) {
		if ( $str ) {
			$item_array = explode($delimiter, $str);
			
			$tree_idx = "";
			foreach ( $item_array as $item ) {
				// $tree_idx .= "['$item']";
				$tree_idx .= "['{$item}']";
			}
			//$cmd = "$rtn{$tree_idx}['_value'] = $val";
			$cmd = "\$rtn{$tree_idx}['_value'] = \$val;";
		} else {
			$cmd = "\$rtn['_value'] = \$val;";
		}
		eval($cmd);
	}
	return $rtn;
}


function make_list_parse_tree($tree, &$str_val_list, $delimiter=".", $current_idx="")
{
	if ( $current_idx ) {
		$str_val_list[$current_idx] = $tree['_value'];
		$current_idx .= $delimiter;
	}

	if ( is_array($tree) ) {
		foreach ( $tree as $sub_key => $sub_tree ) {
			if ( $sub_key == "_value" ) continue;
			make_list_parse_tree($sub_tree, $str_val_list, $delimiter, $current_idx.$sub_key);
		}
	} else {
		echo "\n<br>$current_idx is not array";
	}
}


function echo_tree($tree)
{
	foreach ( $tree as $key => $val ) if ( $key != "_value" ) $has_child = true;
	if ( $has_child ) {
		echo "\n<ul>";
		foreach ( $tree as $key => $val ) {
			if ( $key == "_value" ) continue;
			$_value = $val["_value"];
			echo "\n<li>$_value";
			echo_tree($val);
			echo "\n</li>";
		}
		echo "\n</ul>";
	}
}

function print_debug_msg($title)
{
	echo "\n<p style='margin: 0 0 5px 10px;'>".date("Y-m-d H:i:s")." $title (used memory: ".number_format(memory_get_usage(), 0, ".", ",").")</p>";
}

function make_in_query($arr)
{
	if ( !$arr ) return "'_unused'";

	$in = "";
	foreach ( $arr as $v ) {
		if ( $in ) $in .= ",";
		$in .= sprintf("'%s'", add_to_query($v));
	}
	return $in;
}

function timestamp_init(&$tval)
{
	$tval = microtime(1);
}

function timestamp_lap(&$tval, $msg)
{
	$prev = $tval;
	$tval = microtime(1);
	return sprintf("%0.3f %s (%sk)",  $tval-$prev, $msg, number_format(memory_get_usage()/1000, 0, ".", ","));
}



function make_trie(&$str_val_list, $option=array())
{
	$trie = array();
	foreach ( $str_val_list as $str => $val) {
	
		$token_array = tokenize_string($str, $option);

		$full_idx = "";
		foreach ( $token_array as $token ) {
			$idx = addslashes($token['str']);
			$full_idx .= "['{$idx}']";
		}
		$cmd = "\$trie{$full_idx}['_val'] = \$val;";
		$pass = eval($cmd);
		if ( $pass === false ) echo "\n<br>create error: $full_idx";
	}
	return $trie;
}

function tokenize_string($string, $option=array())
{
	$token_array = array();
	$rpos_list = array();

	if ( !$string ) return $token_array;

	$token_pattern = '(\W)';
	preg_match_all($token_pattern, $string, $out, PREG_OFFSET_CAPTURE|PREG_SET_ORDER);
	if ( count($out) >= 1 ) { 
		foreach ( $out as $match ) {
			$word = $match[0][0];
			$lpos = $match[0][1];
			if ( $lpos > 0 ) $rpos_list[$lpos-1] = $word;	
			$rpos_list[$lpos] = $word;						
		}
	}
	$rpos_list[strlen($string)-1] = true;

	if ( $option['split_digit'] ) {
		$token_pattern = '(\d+)';	// any decimal digit 
		preg_match_all($token_pattern, $string, $out, PREG_OFFSET_CAPTURE|PREG_SET_ORDER);
		if ( count($out) >= 1 ) { 
			foreach ( $out as $match ) {
				$lpos = $match[0][1];
				if ( $lpos > 0 ) $rpos_list[$lpos-1] = 'digit';	// spliting "a12", not "12a"
				$len = strlen($match[0][0]);
				$rpos_list[$lpos+$len-1] = 'digit';
			}
		}
	}
		
	if ( $option['using_variable'] ) {
		$nonsplit_list = array();
		$token_pattern = '(\{\#(.*?)\})';
		preg_match_all($token_pattern, $string, $out, PREG_OFFSET_CAPTURE|PREG_SET_ORDER);
		if ( count($out) >= 1 ) { 
			foreach ( $out as $match ) {
				$lpos = $match[0][1];
				$rpos = $lpos + strlen($match[0][0]) - 1;
				for ( $k = $lpos ; $k < $rpos ; $k++ ) $nonsplit_list[$k] = true;
			}
		}

		$trpos_list = $rpos_list;
		foreach ( $trpos_list as $rpos => $rpos_val ) {
			if ( $nonsplit_list[$rpos] ) unset($rpos_list[$rpos]);
		}
	}

	ksort($rpos_list);
	$lpos = 0;
	foreach ( $rpos_list as $rpos => $word_splitter ) {
		$len = $rpos - $lpos + 1;
		$str = substr($string, $lpos, $len);
		$str = trim($str);
		if ( strlen($str) ) $token_array[] = array('str'=>$str, 'lpos'=>$lpos, 'rpos'=>$rpos);
		$lpos = $rpos+1;
	}
	
	return $token_array;
}

function normalize_token_array(&$token_array, $option = array())
{
	global $normal_word_list;
	if ( !isset($normal_word_list) ) {
		load_normal_word_list($option);
	}
	
	$ntoken_array = array();
	foreach ( $token_array as $token ) {

		$nstr = make_1ch_lower($token['str']);
		if ( $normal_word_list[$nstr] ) {
			$nstr = $normal_word_list[$nstr];
		} else if ( !$unused_word_list[$nstr] ) {
			$nstr = make_singular($nstr);
		}
		$ntoken_array[] = array('str'=>$nstr, 'lpos'=>$token['lpos'], 'rpos'=>$token['rpos'], 'idx_word'=>$token['idx_word']);
	}	
	return $ntoken_array;
}

function load_normal_word_list($option = array())
{
	global $normal_word_list;

	$normal_word_list = array();

	$unused_word_list = array();
	$query = "select str, cit from LRAGR where sca not in ('noun','verb')";
	$result = mysql_query($query) or die("\n<br>Query:$query\n<br>Error:".mysql_error());
	while( $row = mysql_fetch_array($result) ) {
		$str = make_1ch_lower($row['str']);
		$cit = make_1ch_lower($row['cit']);
		
		$str_token_array = tokenize_string($str, $option);
		$cit_token_array = tokenize_string($cit, $option);
		
		if ( count($str_token_array) > 1 ) continue;						
		if ( count($cit_token_array) > 1 ) continue;						
		
		$unused_word_list[$str] = $cit;
	}		
	mysql_free_result($result);

	$query = "select str, cit from LRAGR where sca ='verb'";
	$result = mysql_query($query) or die("\n<br>Query:$query\n<br>Error:".mysql_error());
	while( $row = mysql_fetch_array($result) ) {
		$str = make_1ch_lower($row['str']);
		$cit = make_1ch_lower($row['cit']);
		
		if ( $unused_word_list[$str] ) continue;
		
		$str_token_array = tokenize_string($str, $option);
		$cit_token_array = tokenize_string($cit, $option);
		
		if ( count($str_token_array) > 1 ) continue;						
		if ( count($cit_token_array) > 1 ) continue;						
		
		$normal_word_list[$str] = $cit;
	}		
	mysql_free_result($result);

	$query = "select str, cit from LRAGR where sca = 'noun'";
	$result = mysql_query($query) or die("\n<br>Query:$query\n<br>Error:".mysql_error());
	while( $row = mysql_fetch_array($result) ) {
		$str = make_1ch_lower($row['str']);
		$cit = make_1ch_lower($row['cit']);
		
		if ( $unused_word_list[$str] ) continue;
		
		$str_token_array = tokenize_string($str, $option);
		$cit_token_array = tokenize_string($cit, $option);
		
		if ( count($str_token_array) > 1 ) continue;						
		if ( count($cit_token_array) > 1 ) continue;						
		
		$normal_word_list[$str] = $cit;
	}		
	mysql_free_result($result);

	unset($unused_word_list);
}

function make_1ch_lower($string)
{
	if ( strlen($string) < 3 ) return $string;
	
	$token_pattern = '(\w+)';
	preg_match_all($token_pattern, $string, $out, PREG_OFFSET_CAPTURE|PREG_SET_ORDER);
	if ( count($out) >= 1 ) { 
		foreach ( $out as $match ) {
			$word = $match[0][0];

			$lpos = $match[0][1];
			
			$have_lower = false;
			$len = strlen($word);
			for ( $i = 0 ; $i < $len ; $i++ ) {
				$ch = $word[$i];
				if ( 'a' <= $ch && $ch <= 'z' ) $have_lower = true;
			}
			if ( !$have_lower ) continue;
			
			$ch1 = $word[0];
			if ( 'A' <= $ch1 && $ch1 <= 'Z' ) {
				if ( substr($word, 1) == strtolower(substr($word, 1)) ) $string[$lpos] = strtolower($ch1);
			}
		}
	}
	return $string;
}

function find_set_relation($pos_array1, $pos_array2)
{
	$greater_than = true;
	if ( count($pos_array1) < count($pos_array2) ) {
		$pos_array3 = $pos_array1;
		$pos_array1 = $pos_array2;
		$pos_array2 = $pos_array3;
		$greater_than = false;
	}
	
	$pos_list1 = array();
	$pos_list2 = array();
	foreach ( $pos_array1 as $pos ) $pos_list1[$pos] = true;
	foreach ( $pos_array2 as $pos ) $pos_list2[$pos] = true;
	
	$disjoint = true;
	foreach ( $pos_array2 as $pos ) if ( $pos_list1[$pos] ) $disjoint = false;

	$in = false;
	foreach ( $pos_array2 as $pos ) if ( $pos_list1[$pos] ) $in = true;
	
	$out = false;
	foreach ( $pos_array2 as $pos ) if ( !$pos_list1[$pos] ) $out = true;
	
	$overlap = false;
	if ( $in && $out ) $overlap = true;
	
	$subset = false;
	if ( $in && !$out ) $subset = true;
	
	$proper_subset = false;
	$equal = false;
	if ( $subset ) {
		foreach ( $pos_array1 as $pos ) if ( !$pos_list2[$pos] ) $proper_subset = true;
		if ( !$proper_subset ) $equal = true;
	}

	return array('disjoint'=>$disjoint, 'overlap'=>$overlap, 'subset'=>$subset, 'proper_subset'=>$proper_subset, 'equal'=>$equal, 'greater_than'=>$greater_than);
}

// Connected component (graph theory)
// http://en.wikipedia.org/wiki/Connected_component_(graph_theory)
function find_connected_component($node_list, $adjacency_matrix)
{
	$connected_component_array = array();
	
	$prev_set = array();
	$set = array();
	$done_list = array();
	foreach ( $node_list as $n1 => $n1_val ) {
		if ( $done_list[$n1] ) continue;
		
		$set[$n1] = true;
		$done_list[$n1] = true;
		$prev_set = $set;
		
		while ( true ) {
		
			foreach ( $set as $n2 => $n2_val ) {
				if ( !$adjacency_matrix[$n2] ) continue;
				foreach ( $adjacency_matrix[$n2] as $n3 => $n3_val ) {
					$set[$n3] = true;
					$done_list[$n3] = true;
				}
			}
			
			if ( count($prev_set) == count($set) ) break;
			$prev_set = $set;
		}
		$connected_component_array[] = array_keys($set);
		$set = array();
	}
	return $connected_component_array;
}


function query_trim_execute_plan($execute_plan)
{
	$operator = $execute_plan['operator'];
	$operand_array = $execute_plan['operand_array'];
	if ( !$operator ) {
		return $execute_plan;
	} else {
		$new_operand_array = array();
		foreach ( $operand_array as $operand ) {
			$new_operand_array[] = query_trim_execute_plan($operand);
		} 
		
		if ( count($new_operand_array) == 1 ) {
			return $new_operand_array[0];
		} else {
			$new_execute_plan = array();
			$new_execute_plan['operator'] = $operator;
			$new_execute_plan['operand_array'] = $new_operand_array;
			return $new_execute_plan;
		}
	}
	return false;
}

function query_execute($execute_plan, $tmpid_data_type, &$print_user_query, $idx_tmp_table=0)
{
	global $last_idx_tmp_table;
	
	if ( !$last_idx_tmp_table ) {
		$idx_tmp_table = 1;
		$last_idx_tmp_table = 1;
	}

	$operator = $execute_plan['operator'];
	
	if ( !$operator ) {
		// query를 수행하고 결과 값을 return 한다
		$select_name = $execute_plan['select_name'];
		$select_query = $execute_plan['select_query'];
		$print_user_query .= $select_name;
		if ( query_create_temporary_table($select_query, $tmpid_data_type, $idx_tmp_table) ) {
			return true;
		} else {
			$print_user_query .= "(skip)";
			return false;
		}
	} else {
		$operand_array = $execute_plan['operand_array'];
		if ( strtolower($operator) == 'and' ) {
		
			$sub_idx_array = array();
			$print_user_query .= " ( ";
			foreach ( $operand_array as $operand ) {
				$last_idx_tmp_table++; // global
				$sub_idx = $last_idx_tmp_table;
				if ( query_execute($operand, $tmpid_data_type, $print_user_query, $sub_idx) ) {
					// 성공했을 경우에만
					$sub_idx_array[] = $sub_idx;
				}
				$print_user_query .= " AND ";
			}
			$print_user_query = substr($print_user_query, 0, -5)." ) ";

			$first_idx = 0;
			$query_from = "";
			foreach ( $sub_idx_array as $sub_idx ) {
				if ( !$first_idx ) {
					$first_idx = $sub_idx;
					$query_from = "temporary_{$first_idx}";
				} else {
					$query_from .= " join temporary_{$sub_idx} on (temporary_{$first_idx}.tmpid = temporary_{$sub_idx}.tmpid)";
				}
			}
			if ( $first_idx == 0 ) return false; // 자식들중에 성공한 것이 하나도 없다

			$query = "create temporary table if not exists temporary_{$idx_tmp_table} (tmpid $tmpid_data_type, INDEX(tmpid)) engine=MEMORY select temporary_{$first_idx}.tmpid from $query_from group by temporary_{$first_idx}.tmpid";
			return mysql_query($query);

		} else if ( strtolower($operator) == 'or' ) {

			$sub_idx_array = array();
			$print_user_query .= " ( ";
			foreach ( $operand_array as $operand ) {
				$last_idx_tmp_table++; // global
				$sub_idx = $last_idx_tmp_table;
				if ( query_execute($operand, $tmpid_data_type, $print_user_query, $sub_idx) ) {
					// 성공했을 경우에만
					$sub_idx_array[] = $sub_idx;
				}
				$print_user_query .= " OR ";
			}
			$print_user_query = substr($print_user_query, 0, -4)." ) ";
			if ( count($sub_idx_array) == 0 ) return false;	// 자식들중에 성공한 것이 하나도 없다

			$query_union = "";
			foreach ( $sub_idx_array as $sub_idx ) {
				if ( $query_union ) $query_union .= " union ";
				$query_union .= "select temporary_{$sub_idx}.tmpid from temporary_{$sub_idx}";
			}

			$query = "create temporary table if not exists temporary_{$idx_tmp_table} (tmpid $tmpid_data_type, INDEX(tmpid)) engine=MEMORY {$query_union}";
			return mysql_query($query);

		} else if ( strtolower($operator) == '-' ) {
		
			// http://intomysql.blogspot.com/2011/01/mysql-minus-intersect.html

			$sub_idx_array = array();
			$print_user_query .= " ( ";
			$first_idx = 0;
			foreach ( $operand_array as $operand ) {
				$last_idx_tmp_table++; // global
				$sub_idx = $last_idx_tmp_table;
				if ( !$first_idx ) $first_idx = $sub_idx;
				if ( query_execute($operand, $tmpid_data_type, $print_user_query, $sub_idx) ) {
					// 성공했을 경우에만
					$sub_idx_array[] = $sub_idx;
				}
				$print_user_query .= " - ";
			}
			$print_user_query = substr($print_user_query, 0, -3)." ) ";
			if ( !in_array($first_idx, $sub_idx_array) ) return false; // 첫번째 것이 성공하지 못했다면

			$query_from = "";
			$query_where = "";
			foreach ( $sub_idx_array as $sub_idx ) {
				if ( $sub_idx == $first_idx ) {
					$query_from = "temporary_{$first_idx} t{$first_idx}";
				} else {
					$query_from .= " left join temporary_{$sub_idx} t{$sub_idx} on (t{$first_idx}.tmpid = t{$sub_idx}.tmpid)";
					$query_where .= " and t{$sub_idx}.tmpid is null";
				}
			}

			$query = "create temporary table if not exists temporary_{$idx_tmp_table} (tmpid $tmpid_data_type, INDEX(tmpid)) engine=MEMORY select t{$first_idx}.tmpid from $query_from where 1 $query_where group by t{$first_idx}.tmpid";
			return mysql_query($query);
		}
	}
	return false;
}

function query_create_temporary_table($select_query, $tmpid_data_type, $idx_tmp_table)
{
	$query = "create temporary table if not exists temporary_{$idx_tmp_table} (tmpid $tmpid_data_type, INDEX(tmpid)) engine=MEMORY $select_query";
	
	return mysql_query($query);
}

function query_trim_print_user_query($execute_plan, $print_user_query)
{
	if ( $execute_plan['operator'] == 'and' && substr($print_user_query, 0, 3) == ' ( ' && substr($print_user_query, -3) == ' ) ' ) $print_user_query = substr($print_user_query, 3, -3);
	return $print_user_query;
}